Ivanti Neurons for MDM API Basics

System Role

Your implementation of the Ivanti Neurons for MDM Integration API supports the following role:

Tenant Admin – Authorized to make calls related to the tenant owned by the admin, such as creating and updating accounts.

Authentication

The Ivanti Neurons for MDM Integration APIs use Basic Authentication to authorize API calls. You need to add an authentication header when making calls. See the examples provided in the section for how to add authentication to your calls.

Some of the example calls in this guide do not illustrate an authentication component, however, you should add authentication to your actual calls.

GDPR Consideration

If the API user selected to authenticate API calls is associated with a GDPR profile, then Ivanti Neurons for MDM obfuscates the specified fields in the GDPR profile that API calls return.

Typical fields include:

  • User ID

  • User's Name

  • Email Address

  • Phone Number

  • IMEI

  • Serial Number

  • ICCID

  • IMSI

  • MEID

  • IP Address

  • eSIM Identifier

API Limits

If you are using an Ivanti Neurons for MDM API call that is not described in this guide, then that call is unpublished and unsupported.

Rows Parameter Limit

Ivanti Neurons for MDM paginates the results of APIs and limits the maximum number of results returned to 500 per page to avoid performance issues that may occur when retrieving and transferring large data sets.

You may only receive 50 rows in the return if the API call is against the database, for example, getting a list of user groups or device groups.

When making API calls:

  • Do not send a value greater than 500 for the rows parameter. Ivanti Neurons for MDM release 75 and later will return the following error response when encountering API calls that violate the 500 row limit:

    400 Bad Request
    { "errors": { "globalErrors": null, "fieldErrors": [ { "code": "Range", "message": "must be between 1 and 500", "field": "rows" } ] }, "result": null }
  • Paginate your API returns. If you are using any published API that takes as input the rows parameter, but your code is not paginating the returned results, then you should change that code to enforce pagination, extracting objects one page at a time. You can change the number of results returned per page by using the rows parameter, and the set of results returned by using the start parameter. See Controlling Results for complete details and examples.

Controlling Results

Because of Ivanti Neurons for MDM APIs 500 row limit per page described in API Limits, you may need to use the following parameters to avoid hitting the API limit.

Parameter

Description

rows

Syntax: rows=n

Limits the number of records retrieved.

For example, rows=100 returns 100 rows of records.

Do not send a value larger than 500 with the rows parameter because the APIs do not permit a value of greater than 500.

start

Syntax: start=n

Specifies the record on which to start the return.

For example, if you have 200 devices, to get the last 40 devices, use start=160.

Examples

You have 12340 devices and you cannot retrieve them all at once because you need to chunk them up into rows of at most 500 to avoid the 500 row limit described in API Limits.

To get first 100 devices:

&rows=100&start=0

To get second 100 devices:

&rows=100&start=100

To get the last 40 devices from the list ;

&rows=100&start=12300

Sorting Results

You can use the sortFields[0].name and sortFields[0].order parameters to sort results. When sort order is not set for an API, the API returns the response sorted for the fastest response.

Parameter

Description

sortFields[0].name

Syntax: sortFields[0].name=field

Specifies the field on which to sort.

For example, sortFields[0].name=emailAddress sorts on the emailAddress field.

Here it is URL encoded: sortFields%5B0%5D.name=emailAddress

sortFields[0].order

Syntax: sortFields[0].order=[ASC][DESC]

Specifies ascending or descending sort order.

For example, sortFields[0].order=ASC sorts in ascending order.

Here it is URL encoded: sortFields%5B0%5D.order=ASC

Searching for devices efficiently

You can use the sortfields and searchAfterValues parameters to search for devices efficiently and with good performance. This strategy applies to GET /api/v1/device calls, and is especially useful in environments with ten-thousand or more devices.

To perform the searches:

  1. Issue the first request, using the sortFields parameter to sort on a unique value, for example id:

    https://[Ivanti Neurons for MDM]/api/v1/device?q=&rows=<paginationSize>&dmPartitionId=<devicePartitionId>&sortFields[0].name=id&sortFields[0].order=ASC&nav=true

    sortFields:

    • Can be an array of fields as long as there is one unique field present as a tiebreaker. Ensure that you are passing the same sortFields array in step 2 as you use in step 1.

    • The number and order of fields passed as sort fields must match with the number and order of fields to be passed in the searchAfterValues parameter.

  2. Issue the second request onwards, using the sortFields parameter to sort on the same field(s) and in the same order, and passing the value for sortFields in the last found sort record to the searchAfterValues parameter:

    https://[Ivanti Neurons for MDM]/api/v1/device?q=&rows=<pageSize>&dmPartitionId=<devicePartitionId>&sortFields[0].name=id&sortFields[0].order=ASC&nav=true&searchAfterValues[0]=<last record device id from previous search result>

    For device searches, do not use the start parameter if the number you would use is 10000 or more. Instead use the searchAfterValues parameter. The start parameter searches the entire record set and returns rows after the value specified, whereas, searchAfterValues ignores the record set earlier than the supplied value for searchAfterValues, saving search time.

Example Device Search Session - Three Successive Calls

First call

https://[Ivanti Neurons for MDM]/api/v1/device?q=&rows=10&dmPartitionId=23071&sortFields[0].name=id&sortFields[0].order=ASC&nav=true

{
    "errors": null, 
    "result": {
        "totalCount": 54, 
        "searchResults": [
            {
                "id": 22184, 
               ...
            }, 
            {
                "id": 22185, 
               ...
            }, 
            {
                "id": 22186, 
               ...
            {
                "id": 22187, 
               ...
            }, 
            {
                "id": 22188, 
                ...
            }, 
            {
                "id": 22189, 
                ...
            }, 
            {
                "id": 22190, 
                ...
            }, 
            {
                "id": 22191, 
                ...
            }, 
            {
                "id": 22192, 
                ...
            }, 
            {
                "id": 22194, 
               ...
            }
        ], 
        ...
}

Second Call

https://[Ivanti Neurons for MDM]/api/v1/device?q=&rows=10&dmPartitionId=23071&sortFields[0].name=id&sortFields[0].order=ASC&nav=true&searchAfterValues[0]=22194

{
    "errors": null, 
    "result": {
        "totalCount": 54, 
        "searchResults": [
            {
                "id": 22195, 
               ...
            }, 
            ... 
            ...
            ...
            ... 
            ... 
            ... 
            ... 
            ... 
            {
                "id": 22204, 
               ...
            }
        ], 
        ...
}

Third Call

https://[Ivanti Neurons for MDM]/api/v1/device?q=&rows=10&dmPartitionId=23071&sortFields[0].name=id&sortFields[0].order=ASC&nav=true&searchAfterValues[0]=22204

{
    "errors": null, 
    "result": {
        "totalCount": 54, 
        "searchResults": [
            {
                "id": 22205, 
               ...
            }, 
            ... 
            ...
            ...
            ... 
            ... 
            ... 
            ... 
            ... 
            {
                "id": 22215, 
               ...
            }
        ], 
        ...
}

Searching for users efficiently

You can use the sortFields and searchAfterValues parameters to search for users efficiently and with good performance. This strategy applies to GET /api/v1/account calls, and is especially useful in environments with ten-thousand or more users.

To perform the searches:

  1. Issue the first request, using the sortFields parameter to sort on a unique value, for example, id:

    https://[Ivanti Neurons for MDM]/api/v1/account?q=&rows=<paginationSize>&start=0&fq=&sortFields[0].name=id&sortFields[0].order=ASC&nav=true

    sortFields:

    • Can be an array of fields as long as there is one unique field present as a tiebreaker. Ensure that you are passing the same sortFields array in step 2 as you use in step 1.

    • The number and order of fields passed as sort fields must match with the number and order of fields to be passed in the searchAfterValues parameter.

  2. Issue the second request onwards, using the sortFields parameter to sort on the same field(s) and in the same order, and passing the value for sortFields in the last found sort record to the searchAfterValues parameter:


    https://[Ivanti Neurons for MDM]/api/v1/account?q=&rows=<pageSize>&start=0&fq=&sortFields[0].name=id&sortFields[0].order=ASC&nav=true&searchAfterValues[0]=<last record account id from previous search result>

    For user searches, do not use the start parameter if the number you would use is 10000 or more. Instead use the searchAfterValues parameter. The start parameter searches the entire record set and returns rows after the value specified, whereas, searchAfterValues ignores the record set earlier than the supplied value for searchAfterValues, saving search time.

Example User Search Session - Three Successive Calls

Example Request

First call

https://[Ivanti Neurons for MDM]/api/v1/account?q=&rows=10&start=0&fq=&sortFields[0].name=id&sortFields[0].order=ASC&nav=true

Example Response

{ "

errors": null,

"result": {

"totalCount": 44,

"searchResults": [

{ "

id": 10002,

...

},

{ "

id": 10003,

...

},

{ "

id": 10004,

...

},

{ "

id": 10005,

...

}{ "

id": 10006,

...

}{ "

id": 10007,

...

}

{ "

id": 10008,

...

}{ "

id": 10009,

...

}{ "

id": 10010,

...

}{ "

id": 10011,

...

} ],

...

}

  

Second call

https://[Ivanti Neurons for MDM]/api/v1/account?q=&rows=10&start=0&fq=&sortFields[0].name=id&sortFields[0].order=ASC&nav=true&searchAfterValues[0]=10011

{ "

errors": null,

"result": {

"totalCount": 44,

"searchResults": [

{ "

id": 10012,

...

},

{ "

id": 10013,

...

},

...

...

...

...

...

...

...

{ "

id": 10021,

...

} ],

...

}

 

Third call

https://[Ivanti Neurons for MDM]/api/v1/account?q=&rows=10&start=0&fq=&sortFields[0].name=id&sortFields[0].order=ASC&nav=true&searchAfterValues[0]=10021

{ "

errors": null,

"result": {

"totalCount": 44,

"searchResults": [

{ "

id": 10022,

...

},

...

...

...

...

...

...

...

...

{ "

id": 10031,

...

} ],

...

}

HTTP Response Codes

The API issues the codes listed below in its responses, and issues a “Success” message for successful calls. When a call fails, the API issues a descriptive error message.

  • 200 OK - Success
  • 400 Bad request - The request was invalid. The accompanying error message in the output explains the reason.
  • 401 Unauthorized - Authentication to the API has failed. Authentication credentials are missing or wrong.
  •  403 Forbidden – You are trying to access a resource that does not belong to you.
  • 404 Not found - The requested resource is not found. The accompanying error message explains the reason.
  • 500 Internal Server Error - An internal server error has occurred while processing the request.
  • 502 Bad Gateway - The Ivanti Neurons for MDM server is not reachable.

Response Types

The API can return responses in JSON.

Common Response Objects

This section contains descriptions of the common response objects returned by the API.

Error

This object represents error response.

{ "fieldErrors": [ { object(FieldError ) } ], "globalErrors": [ { object(GlobalError ) } ] }

Field

Description

Field

Description

fieldErrors[]

object(FieldError )

A list of errors related to request parameters.

globalErrors[]

object(GlobalError )

A list of general errors.

FieldError

This object represents errors related to request parameters.

{ "code": string, "field": string, "message": string }

Field

Description

code

string

HTTP response error code as documented in the API guide.

field

string

The request field that has an error.

message

string

Localized description of the error message.

GlobalError

This object represents global errors.

{ "code": string, "message": string }

Field

Description

code

string

HTTP response error code as documented in the API guide.

message

string

Localized description of the error message.

The Importance of the Device Space ID

The device space ID is an important value in Ivanti Neurons for MDM and is needed to make a variety of device-related API calls. You can get the default device space ID by examining the response of the GET Tenant Metadata call, described in the section, Get Device Enrollment Program (DEP) details by DEP profile ID. You can get a list of all device spaces in a tenant using the Get Device Spaces call. The device space ID appears as shown below in the Get Tenant Metadata call:

      "defaultDmPartitionId": 23004,

Note: Device “spaces” were previously named device “partitions” in the Ivanti Neurons for MDM user interface, however, the term “partition” remains in API parameters and returns.